﻿// Copyright 2009 Mike Geise
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

namespace Falcon.Forums.Services
{
	using System.Collections.Generic;
	using Falcon.Core.Domain;
	using Falcon.Core.Domain.Services;
	using Falcon.Core.Domain.Values;
	using Falcon.Forums.Domain;
	using Falcon.Forums.Domain.Repositories;
	using Falcon.Forums.Domain.Services;

	public class ForumPostAttachmentService : IForumPostAttachmentService
	{
		/// <summary>
		/// Initializes a new instance of the <see cref="ForumPostAttachmentService"/> class.
		/// </summary>
		/// <param name="attachmentService">The attachment service.</param>
		/// <param name="attachmentStoreService">The attachment store service.</param>
		/// <param name="forumPostAttachmentRepository">The forum post attachment repository.</param>
		public ForumPostAttachmentService(
			IAttachmentService attachmentService,
			IAttachmentStoreService attachmentStoreService,
			IForumPostAttachmentRepository forumPostAttachmentRepository)
		{
			this.AttachmentService = attachmentService;
			this.AttachmentStoreService = attachmentStoreService;
			this.ForumPostAttachmentRepository = forumPostAttachmentRepository;
		}

		/// <summary>
		/// Gets or sets the attachment service.
		/// </summary>
		/// <value>The attachment service.</value>
		public IAttachmentService AttachmentService
		{
			get;
			private set;
		}

		/// <summary>
		/// Gets or sets the attachment store service.
		/// </summary>
		/// <value>The attachment store service.</value>
		public IAttachmentStoreService AttachmentStoreService
		{
			get;
			private set;
		}

		/// <summary>
		/// Gets or sets the forum post attachment repository.
		/// </summary>
		/// <value>The forum post attachment repository.</value>
		public IForumPostAttachmentRepository ForumPostAttachmentRepository
		{
			get;
			private set;
		}

		/// <summary>
		/// Gets all the attachment relations by the specified specification.
		/// </summary>
		/// <param name="specification">The specification.</param>
		/// <returns></returns>
		public IList<ForumPostAttachment> GetAll(ForumPostAttachmentSpecification specification)
		{
			return this.ForumPostAttachmentRepository.GetAll(specification);
		}

		/// <summary>
		/// Gets all the attachment relations by the specified values.
		/// </summary>
		/// <param name="values">The values.</param>
		/// <returns></returns>
		public Dictionary<int, IList<Attachment>> GetAll(int[] values)
		{
			var specification = new ForumPostAttachmentSpecification
			{
				PostId = values
			};

			var results = this.GetAll(specification);
			var relations = new Dictionary<int, IList<Attachment>>();

			foreach (var relation in results)
			{
				if (!relations.ContainsKey(relation.PostId))
				{
					relations.Add(relation.PostId, new List<Attachment>());
				}

				relations[relation.PostId].Add(relation.Attachment);
			}

			return relations;
		}

		/// <summary>
		/// Creates the attachment relation.
		/// </summary>
		/// <returns></returns>
		public ForumPostAttachment Create()
		{
			return new ForumPostAttachment();
		}

		/// <summary>
		/// Process the forum post attachment.
		/// </summary>
		/// <param name="post">The post.</param>
		/// <param name="value">The attachment value.</param>
		/// <param name="attachments">The attachments.</param>
		/// <returns></returns>
		public bool Process(ForumPost post, AttachmentCreate value, IList<ForumPostAttachment> attachments)
		{
			if (value.Source != null && value.Source.ContentLength > 0)
			{
				var attachment = AttachmentService.Create();

				AttachmentService.Insert(attachment, value);

				var relation = this.Create();

				this.Insert(relation, post, attachment);

				attachments.Add(relation);

				return true;
			}

			return false;
		}

		/// <summary>
		/// Inserts the specified relation.
		/// </summary>
		/// <param name="relation">The relation.</param>
		public void Insert(ForumPostAttachment relation)
		{
			this.ForumPostAttachmentRepository.Insert(relation);
		}

		/// <summary>
		/// Inserts the forum post attachments into the storage.
		/// </summary>
		/// <param name="post">The post.</param>
		/// <param name="attachments">The attachments.</param>
		public void Insert(ForumPost post, IList<AttachmentStore> attachments)
		{
			foreach (var store in attachments)
			{
				var relation = this.Create();

				this.Insert(relation, post, store.Attachment);

				this.AttachmentStoreService.Delete(store, false);
			}
		}

		/// <summary>
		/// Deletes the specified relation.
		/// </summary>
		/// <param name="relation">The relation.</param>
		public void Delete(ForumPostAttachment relation)
		{
			this.ForumPostAttachmentRepository.Delete(relation);
		}

		/// <summary>
		/// Inserts the specified relation.
		/// </summary>
		/// <param name="relation">The relation.</param>
		/// <param name="post">The post.</param>
		/// <param name="attachment">The attachment.</param>
		private void Insert(ForumPostAttachment relation, IEntity<ForumPost> post, Attachment attachment)
		{
			relation.PostId = post.Id;
			relation.Attachment = attachment;

			this.Insert(relation);
		}
	}
}